package com.simen.hellobytes.android;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Build;
import android.util.Log;

import java.security.MessageDigest;

/**
 * author: SimenHi
 * create time: 2019-12-26 18:30
 * description:
 */
public class PackageUtil {

    private static final String TAG = PackageUtil.class.getSimpleName();

    /**
     * 获取md5指纹信息(签名文件不同,md5指纹也不同;不同包名app可以具有相同的md5指纹信息)
     * 示例输出:
     * sign: 55:2e:ba:e6:b4:7e:ac:e3:02:58:64:9a:db:82:87:b6
     */
    public static String getMd5Fingerprint(Context context) {
        try {
            PackageManager pm = context.getPackageManager();

            Signature sig = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures[0];

            return doFingerprint(sig.toByteArray(), "MD5");
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public static String getApkMd5Fingerprint(Context context, String apkPath) {
        PackageManager packageManager = context.getPackageManager();

        PackageInfo packageInfo = packageManager.getPackageArchiveInfo(apkPath, PackageManager.GET_SIGNATURES);

        if (packageInfo != null) {
            try {
                return doFingerprint(packageInfo.signatures[0].toByteArray(), "MD5");
            } catch (Exception e) {
            }
        }

        return null;
    }

    public static boolean isReleasePackage(Context context,String apkPath){
        PackageManager packageManager = context.getPackageManager();

        PackageInfo packageInfo = packageManager.getPackageArchiveInfo(apkPath, PackageManager.GET_SIGNATURES);

        if (packageInfo != null) {
            return isReleasePackage(packageInfo.applicationInfo);
        }

        return false;
    }

    public static boolean isReleasePackage(ApplicationInfo applicationInfo){
        boolean debug = (applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;

        return !debug;
    }

    private static String doFingerprint(byte[] certificateBytes, String algorithm) throws Exception {
        MessageDigest md = MessageDigest.getInstance(algorithm);

        md.update(certificateBytes);

        byte[] digest = md.digest();
        StringBuilder toRet = new StringBuilder();
        for (int i = 0; i < digest.length; i++) {
            if (i != 0) {
                toRet.append(":");
            }
            int b = digest[i] & 0xff;
            String hex = Integer.toHexString(b);
            if (hex.length() == 1) {
                toRet.append("0");
            }
            toRet.append(hex);
        }

        return toRet.toString();
    }

    /**
     * Check whether the specified package name is installed or not.
     * @param context
     * @param packageName
     * @return
     */
    public static boolean isPackageInstalled(Context context, String packageName) {
        PackageInfo packageInfo;
        try {
            PackageManager pm=context.getPackageManager();
            if(pm==null){
                Log.i(TAG, "getPackageManager return null");
                return false;
            }

            if(Build.VERSION.SDK_INT>=28){
                //PackageManager.GET_SIGNING_CERTIFICATES 0x08000000
                packageInfo=pm.getPackageInfo(packageName,0x08000000);
            }else {
                //PackageManager.GET_SIGNATURES 64 (0x00000040)
                packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
            }
            return packageInfo != null;
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }

    public static boolean launchPackage(Context context,String packageName){
        PackageManager pm=context.getPackageManager();
        Intent launchIntent=pm.getLaunchIntentForPackage(packageName);
        try {
            if(launchIntent!=null) {
                context.startActivity(launchIntent);
                return true;
            }
        }catch (Exception e){
        }
        return false;
    }

}
